//
//  knx_interface.h
//  knx_lib
//
//  Created by hinwo-apple on 13-6-5.
//  Copyright (c) 2013年 Hinwo. All rights reserved.
//

#ifndef knx_lib_knx_interface_h
#define knx_lib_knx_interface_h

#ifdef   __cplusplus
extern "C"
{
#endif
    
#ifndef NULL
#define NULL    0
#endif

typedef char                _string;
typedef unsigned char		_u8;
typedef unsigned short		_u16;
typedef unsigned int		_u32;
typedef int                 _int32;

#define KNX_NETWORK_MODE_IPR        0
#define KNX_NETWORK_MODE_IPS        1
#define KNX_NETWORK_MODE_AUTO       3
#define SERVER_PORT 3671
#define KNX_MULTICAST_ADDRESS           "224.0.23.12"
#define IP_BYTE_3(ip)   ((unsigned char)((ip>>24)&0xff))
#define IP_BYTE_2(ip)   ((unsigned char)((ip>>16)&0xff))
#define IP_BYTE_1(ip)   ((unsigned char)((ip>>8)&0xff))
#define IP_BYTE_0(ip)   ((unsigned char)(ip&0xff))

#define PORT_BYTE_HI(port)   ((unsigned char)((port>>8)&0xff))
#define PORT_BYTE_LOW(port)   ((unsigned char)(port&0xff))

typedef void (* BYTES_MSG_CALLBACK)(_u8 *device_addr,_u8 *value,_u8 len,void *userdata);
typedef void (* ONE_BIT_MSG_CALLBACK)(_u8 *device_addr,_u8 value,void *userdata);

typedef void (* SERVER_ERROR_CALLBACK)(_string *msg,_int32 errcode1,_int32 errcode2);

typedef struct{
    _u8 _connect_mode;
    _u8 _device_status;
    _u8 _individual_addr[2];
    _u8 _port[2];
    _u8 _ip_addr[4] ;
    _u8 _multicast_addr[4];
    _u8 _mac_addr[6];
    _u8 _serial_num[8];
    _string _device_friendly_name[30] ;
} KNX_SERVER;

typedef enum{
    ONE_BIT_VALUE = 0x0,
    TWO_BIT_VALUE = 0x01,
    THREE_BIT_VALUE = 0x02,
    FOUR_BIT_VALUE = 0x03,
    FIVE_BIT_VALUE = 0x04,
    SIX_BIT_VALUE = 0x05,
    SEVEN_BIT_VALUE = 0x06,
    ONE_BYTE_VALUE = 0x07,
    TWO_BYTES_VALUE = 0x08,
    THREE_BYTES_VALUE = 0x09,
    FOUR_BYTES_VALUE =0xA,
    SIX_BYTES_VALUE = 0xB,
    EIGHT_BYTES_VALUE = 0xC,
    TEN_BYTES_VALUE = 0xD,
    FOURTEEN_BYTES_VALUE = 0xE,
    ZERO_TO_FOURTEEN_BYTES = 0xF    
}DATA_TYPE;

typedef enum{
    UNSIGNED_INT = 0x0,
    SIGNED_INT = 0x01,
    FLOAT = 0x02,
    THREE_BYTES_DATE = 0x03,
    THREE_BYTES_TIME = 0x04,
    PERCENT = 0x5
}DATA_DEFINE;

typedef struct
{
    ONE_BIT_MSG_CALLBACK _onebit_callback;
    BYTES_MSG_CALLBACK _bytes_callback;
}KNX_MSG_CALLBACK;

/*
 KNX data struct
*/

typedef struct{
    _u32 dayOfWeek;
    _u32 hour;
    _u32 min;
    _u32 second;
}KNX_VALUE_TIME;

typedef struct{
    _u32 dayOfMonth;
    _u32 month;
    _u32 years;
}KNX_VALUE_DATE;

/* value */

void short_2bytes(_u8 *value, _u8 data[2]);
void bytes2_short(_u16 *value,short *svalue, _u8 data[2]);

void degree_2bytes(_int32 degree,_u8 data[2]);
void bytes_2_degree(_u8 data[2],float *degree);

_u8 onebit_parser(_u8 data[]);
_u8 onebyte_parser(_u8 *data,_u8 len);

void bytes3_2_time(_u8 data[3],KNX_VALUE_TIME *time);
void bytes3_2_date(_u8 data[3],KNX_VALUE_DATE *date);

void bytes3_2_time(_u8 data[3],KNX_VALUE_TIME *time);
void bytes3_2_date(_u8 data[3],KNX_VALUE_DATE *date);

void date_2_bytes3(_u8 data[3],KNX_VALUE_DATE *date);
void time_2_bytes3(_u8 data[3],KNX_VALUE_TIME *time);

void int_4bytes(_u8 *value, _u8 data[4]);
void bytes4_int(_u32 *value,int *svalue, _u8 data[4]);

void float_4bytes(_u8 *value, _u8 data[4]);
void bytes4_float(_u8 *floatValue, _u8 data[4]);

//4 bytes with network format covert to float
float bytes4_network_2_float(_u8 data[4]);
_int32 isBigEndion();

#define KNX_LIB_ERROR_BASE              (-1024)
#define KNX_SERVER_DISCONNECT           (KNX_LIB_ERROR_BASE - 1)
#define KNX_LIB_IS_INIT                 (KNX_LIB_ERROR_BASE - 2)
#define KNX_LIB_IS_UNINIT               (KNX_LIB_ERROR_BASE - 3)
#define KNX_LIB_IS_SLEEP                (KNX_LIB_ERROR_BASE - 4)


_int32 KNX_lib_init(_string *addr_ips);
_int32 KNX_lib_uninit();
_int32 KNX_lib_network_mode(_string **addr_server);      // 0: ipr , 1:ips
_int32 KNX_lib_sleep();
_int32 KNX_lib_wakeup();
_int32 KNX_set_error_callback(SERVER_ERROR_CALLBACK callback);
_int32 KNX_message_set_callback(KNX_MSG_CALLBACK callback);

_int32 eib_objects_edit_start();
_int32 eib_object_register(_string *addr,_u16 addr_type,_u16 data_type,void *user_data);
_int32 eib_object_unregister(_u8 *addr,_u16 addr_type);
_int32 eib_objects_edit_finish();
_int32 eib_object_status_update();


_int32 write_device_value(_u8 addr[2],_u8 addr_type,_u8 value_type,_u8 *data,_u32 len);
_int32 read_device_status(_u8 addr[2],_u8 addr_type,_u8 value_type);

void print_data(_string *title,void *src,_int32 len);


    
#ifdef   __cplusplus
}
#endif

#endif
